package org.linlinjava.litemall.db.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import org.linlinjava.litemall.db.dao.LitemallOrderTotalReturnHistoryMapper;
import org.linlinjava.litemall.db.dao.LitemallOrderTotalReturnMapper;
import org.linlinjava.litemall.db.domain.LitemallOrderTotalReturn;
import org.linlinjava.litemall.db.domain.LitemallOrderTotalReturnHistory;

import org.linlinjava.litemall.db.domain.LitemallRentOrder;
import org.linlinjava.litemall.db.domain.ReturnGoodsList;
import org.linlinjava.litemall.db.dto.RentPartGoodsDto;
import org.linlinjava.litemall.db.exception.ServiceException;
import org.linlinjava.litemall.db.service.LitemallOrderTotalReturnHistoryService;
import org.linlinjava.litemall.db.service.LitemallRentOrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class LitemallOrderTotalReturnHistoryServiceImpl extends
        ServiceImpl<LitemallOrderTotalReturnHistoryMapper, LitemallOrderTotalReturnHistory>
        implements LitemallOrderTotalReturnHistoryService {

    @Autowired
    private LitemallOrderTotalReturnMapper litemallOrderTotalReturnMapper;
    @Autowired
    private LitemallRentOrderService litemallRentOrderService;

    @Override
    public List<ReturnGoodsList> getReturnGoodsListByOrderId(Long orderId) {

        return baseMapper.getReturnGoodsListByOrderId(orderId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void rentPartGoods(RentPartGoodsDto partGoodsDto) {
        LitemallRentOrder rentOrder = litemallRentOrderService.findById(Integer.valueOf(partGoodsDto.getRentOrderId().toString()));
        List<ReturnGoodsList> lists = getReturnGoodsListByOrderId(partGoodsDto.getRentOrderId());
        LitemallOrderTotalReturn orderTotalReturn = litemallOrderTotalReturnMapper
                .selectOne(Wrappers
                        .<LitemallOrderTotalReturn>lambdaQuery()
                        .eq(LitemallOrderTotalReturn::getOrderId, partGoodsDto.getRentOrderId())
                );
        if (ObjectUtil.isEmpty(orderTotalReturn)) {
            orderTotalReturn = new LitemallOrderTotalReturn();
        }
        orderTotalReturn.setOrderId(partGoodsDto.getRentOrderId());
        orderTotalReturn.setOrderNum(rentOrder.getRentOrderSn());
        orderTotalReturn.setTotal(lists.size());
        List<Long> num = Arrays.stream(
                        partGoodsDto.getRentGoodsIds()
                                .replace("[", "")
                                .replace("]", "")
                                .split(",")
                )
                .filter(s -> !s.trim().isEmpty())
                .map(Long::parseLong).collect(Collectors.toList());

        orderTotalReturn.setReturnNum(ObjectUtil.isEmpty(orderTotalReturn.getReturnNum()) ? num.size() : orderTotalReturn.getReturnNum() + num.size());
        orderTotalReturn.setNotReturnNum(orderTotalReturn.getTotal() - orderTotalReturn.getReturnNum());
        orderTotalReturn.setCreateTime(ObjectUtil.isEmpty(orderTotalReturn.getCreateTime()) ? new Date() : orderTotalReturn.getCreateTime());
        orderTotalReturn.setUpdateTime(new Date());
        if (ObjectUtil.isEmpty(orderTotalReturn.getId())) {
            litemallOrderTotalReturnMapper.insert(orderTotalReturn);
        } else {
            litemallOrderTotalReturnMapper.updateById(orderTotalReturn);
        }

        List<LitemallOrderTotalReturnHistory> historyList = this.list(
                Wrappers.<LitemallOrderTotalReturnHistory>lambdaQuery()
                        .eq(LitemallOrderTotalReturnHistory::getOrderId, partGoodsDto.getRentOrderId())
        );
        List<Long> goodsIds = new ArrayList<>();

        if (ObjectUtil.isNotEmpty(historyList)) {
            for (LitemallOrderTotalReturnHistory history : historyList) {
                goodsIds.addAll(Arrays.stream(
                                history.getReturnIds()
                                        .replace("[", "")
                                        .replace("]", "")
                                        .split(",")
                        )
                        .filter(s -> !s.trim().isEmpty())
                        .map(Long::parseLong).collect(Collectors.toList()));
            }
        }

        List<Long> conflictIds = num.stream()
                .filter(goodsIds::contains)
                .collect(Collectors.toList());

        if (!conflictIds.isEmpty()) {
            throw new ServiceException("以下商品 ID 已经被归还，不能重复归还：" + conflictIds);
        }
        goodsIds.addAll(num);
        LitemallRentOrder litemallRentOrder = litemallRentOrderService.findById(Integer.valueOf(partGoodsDto.getRentOrderId().toString()));

        litemallRentOrderService.updateById(litemallRentOrder);
        if (goodsIds.size() == orderTotalReturn.getTotal()) {
            litemallRentOrder.setRentOrderStatus(9);
        } else {
            litemallRentOrder.setRentOrderStatus(8);
        }
        litemallRentOrderService.updateById(litemallRentOrder);

        LitemallOrderTotalReturnHistory history = new LitemallOrderTotalReturnHistory();
        history.setOrderTotalId(orderTotalReturn.getId());
        history.setOrderId(partGoodsDto.getRentOrderId().toString());
        history.setTotal(num.size());
        history.setReturnIds(partGoodsDto.getRentGoodsIds());
        String names = "";
        Map<Long, String> map = new HashMap<>();
        for (ReturnGoodsList list : lists) {
            map.put(list.getId(), list.getName());
        }
        for (Long id : map.keySet()) {
            names += map.get(id) + ",";
        }
        history.setReturnNames(names);
        this.saveOrUpdate(history);

    }
}